#include <string.h>
#include <stdio.h>
#include <conio.h>

  typedef unsigned char  BYTE;
  typedef unsigned short WORD;
  typedef unsigned long  LONG;

  struct _TEXTDATA
  {
    LONG dtPosi;
    LONG cmPosi;
    LONG dtMaxPosi;
    LONG cmMaxPosi;
    WORD ptData[ 0x0200 ];
  } txt;


  LONG lpCompCount;


  int  y    = 0;
  int  x    = 0;

  FILE *f1;

  char dte[0x100][0x10];
  char cmp[0x200][0x20];
  // Table file load variables

  char buf[256];

  char rfile[512];
  char tfile[512];

  void Table_Loader();

  char Comp( );
  char Dte( );


//--------------------------------//
// Program Main                   //
//--------------------------------//
void main( int argc, char *argv[ ] )
{
//  clrscr( );
  printf("\n");
  //
  if ( argc > 2 )
	{
    strcpy( rfile, argv[1] );
    strcpy( tfile, argv[2] );
  }
  else
  {
    printf("Usage: ROM.ext TABLE.ext" );
    return;
  }

  //
  f1 = fopen( rfile, "r+b" );

  if ( !f1 ){
	  printf("Fatal Error: ROM File not found...%s", rfile );
	  return;
  }// ELSE

  // load the table file
  Table_Loader( );
  //
  Dte( );
	Comp( );
}// END OF MAIN



//-------------------------//
// Insert Compression text //
//-------------------------//
char Comp()
{
  long c,
	     c_len;
  LONG tPosi;

  printf("Inserting dictionary table...");

  // goto pointer table offset
  tPosi = txt.cmPosi;

  // Adjust the position to point at text, not pointers
  txt.cmPosi += 0x0400;
  fseek( f1, txt.cmPosi, SEEK_SET );
  c               = -1;
  txt.ptData[ 0 ] = 0;
  while( ++c < lpCompCount && c < 0x0200 )
	{ // Set pointer
    txt.ptData[ c ] = (txt.cmPosi & 0xFFFF) | 0x8000;
    //
    c_len = strlen( cmp[c] );
    // Make sure we have space
    if ( (txt.cmPosi + c_len + 1) >= txt.cmMaxPosi ){
      clrscr( );
      printf("Error: Compression stopped inserting!\n"
             "String: %s, Index: %04X, was not inserted!",
             cmp[c], c
            );
      //---------------
      return -1;
    }

    fwrite( cmp[ c ], 1, c_len, f1 );
    // Store the End of String character
    fputc( 0xFF, f1 );

    txt.cmPosi += (c_len + 1);
  }// WEND

  // Insert the Pointer Table
  fseek( f1, tPosi, SEEK_SET );
  fwrite( txt.ptData, 2, c, f1 );

	return 0;
}



/**************************
; Insert D.T.E text data  *
**************************/
char Dte( )
{
  long c,
	     c_len;

  printf("Inserting DTE data...");

  // goto pointer table offset
  fseek( f1, txt.dtPosi, SEEK_SET );

  c               = 0x7F;
  while( ++c < 0x0100 )
	{ // Set pointer
    c_len = strlen( dte[c] );
    // Make sure we have space
    if ( (txt.dtPosi + c_len + 1) >= txt.dtMaxPosi ){
      clrscr( );
      printf("Error: DTE stopped inserting!\n"
             "String: %s, Index: %04X, was not inserted!",
             dte[c], c
            );
      //---------------
      return -1;
    }

    fwrite( dte[ c ], 1, c_len, f1 );
    txt.dtPosi += (c_len);
  }// WEND

 return 0;

} // END OF MAIN



//----------------------//
// Table loader routine //
//----------------------//
void Table_Loader( )
{
  int val;
  char buf[256],
	     *p;

  FILE *f2;

  f2 = fopen( tfile, "r+t");

  if ( !f2 ){
    printf("Fatal Error: Can't open the Table File: \"%s\".", tfile );
    exit( 1 );
  }

  //
  lpCompCount = 0;

  //--------------------------//
  //                          //
  //--------------------------//
	while( fgets( buf, 256, f2 ) )
	{ //
    p = strchr( buf, '\r' );
    if ( p ) p[0] = 0;
    //
    p = strchr( buf, '\n' );
    if ( p ) p[0] = 0;

    //----------------//
    // Load the table //
    //----------------//
    if ( buf[2] == '=' && strlen( &buf[3] ) )
	  {
      buf[2] = 0;
//		  strcpy( dte[ strtol( buf, NULL, 16 ) ], &buf[3] );
      val = strtol( buf, NULL, 16 );
      memset( dte[ val ], 0x00, 16 );
      memset( dte[ val ], 0xFF, 8 );
		  memcpy( dte[ val ], &buf[3], strlen( &buf[3] ) );
		}
		else
	  if ( buf[4] == '=' )
		{ //
      buf[4] = 0;
      val = strtol( buf, NULL, 16 ) & 0x01FF;
		  strcpy( cmp[ val ], &buf[5] );
      //
      lpCompCount++;
    }// END IF

    //---------------//
    // Control Codes //
    //---------------//
    if ( !strncmpi( buf, ".MAX_DTE_OFFSET", 15) ){

      sscanf( buf, "%s %lX", &buf[128], &txt.dtMaxPosi );

    } else
    if ( !strncmpi( buf, ".MAX_COMP_OFFSET", 16) ){

      sscanf( buf, "%s %lX", &buf[128], &txt.cmMaxPosi );

    } else
    if ( !strncmpi( buf, ".COMP_OFFSET", 12) ){

      sscanf( buf, "%s %lX", &buf[128], &txt.cmPosi );

    } else
    if ( !strncmpi( buf, ".DTE_OFFSET", 11) ){

      sscanf( buf, "%s %lX", &buf[128], &txt.dtPosi );
    }

  }// WEND


  fclose( f2 );
}



